#include <stdio.h>
#include <stdlib.h>

typedef int ElemType;   //定义数据元素类型

typedef struct DuLNode{     //双向链表结点类型
    ElemType data;  //数据域
    struct DuLNode *prior,*next;//前驱指针和后继指针
}DuLNode,*DuLinkList;//双向链表类型

//获取双向链表中第i个结点的指针
DuLinkList GetElem_DulL(DuLinkList L, int i){
    if (i < 1){
        return NULL;//位置i不合法
    }
    DuLinkList p = L->next;//p指向第1个结点
    int j = 1;//j记录当前结点的位置
    while (p != L && j < i){
        p = p->next;//指向下一个结点
        j++;//位置加1
    }
        return p;//返回第i个结点的指针
}

//创建一个带头结点的空双向链表
DuLinkList CreateList_Dul(){
    DuLinkList L = (DuLinkList)malloc(sizeof(DuLNode)); //创建头结点
    if (L == NULL){ //存储分配失败
        return NULL;//返回空指针
    }
    L->prior = L;//头结点的前驱指针指向自己
    L->next = L;//头结点的后继指针指向自己
    return L;//返回头结点指针
}

int ListInsert_DuL(DuLinkList *L, int i, ElemType e){
    DuLinkList p = GetElem_DulL(*L, i);//获取第i个结点的指针
    if (p == NULL){
        return 0;//第i个结点不存在
    }
    //创建新结点s
    DuLinkList s = (DuLinkList)malloc(sizeof(DuLNode));
    if (s == NULL){
        return 0;//存储分配失败
    }

s->data = e;//将数据元素e赋值给新结点s的数据域
s->prior = p->prior;//新结点s的前驱指针指向p的前驱结点
s->next = p;//新结点s的后继指针指向p结点

if (p->prior != NULL){
    p->prior->next = s;//p的前驱结点的后继指针指向新结点s
    }
p->prior = s;//p结点的前驱指针指向新结点s
return 1;//插入成功
}

int main(){
    DuLinkList L = CreateList_Dul();//创建空双向链表
    ListInsert_DuL(&L, 1, 10);//在位置1插入元素10
    ListInsert_DuL(&L, 2, 20);//在位置2插入元素20
    ListInsert_DuL(&L, 3, 30);//在位置3插入元素30
    ListInsert_DuL(&L, 1, 0);//在位置1插入元素0

    DuLinkList p = L->next;//p指向第1个结点
    while (p != L){
        printf("%d ", p->data);//打印当前结点的数据元素
        p = p->next;//指向下一个结点
    }
    return 0;
}